#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <thread>

void *thread1(void *arg)
{
    std::cout << "thread 1 running ...." << std::endl;
    int *p = (int *)malloc(sizeof(int));
    *p = 1;
    return (void *)p;
}

void *thread2(void *arg)
{
    std::cout << "thread 2 exiting ...." << std::endl;
    int *p = (int *)malloc(sizeof(int));
    *p = 2;
    pthread_exit((void *)p);
}

void *thread3(void *arg)
{
    while (1)
    {
        std::cout << "thread 3 is running ....." << std::endl;
        sleep(1);
    }

    return NULL;
}

int main()
{
    pthread_t tid;
    void *ret;

    // thread 1 return
    pthread_create(&tid, NULL, thread1, NULL);
    pthread_join(tid, &ret);
    printf("thread return, thread id %lx, return code:%d\n", tid, *(int *)ret);
    free(ret);

    // thread 2 exit
    pthread_create(&tid, NULL, thread2, NULL);
    pthread_join(tid, &ret);
    printf("thread return, thread id %lx, return code:%d\n", tid, *(int *)ret);
    free(ret);

    // thread 3 cancel by other
    pthread_create(&tid, NULL, thread3, NULL);
    sleep(3);
    pthread_cancel(tid);
    pthread_join(tid, &ret);
    if (ret == PTHREAD_CANCELED)
        printf("thread return, thread id %lx, return code:PTHREAD_CANCELED\n",
               tid);
    else
        printf("thread return, thread id %lx, return code:NULL\n", tid);

    return 0;
}

// // 全局变量在线程内部是共享的
// int gval = 100;

// std::string ToHex(pthread_t tid)
// {
//     // 进程内的函数，线程共享
//     char buff[64];
//     snprintf(buff, sizeof(buff), "0x%lx", tid);
//     return buff;
// }

// class ThreadData
// {
// public:
//     ThreadData()
//     {
//     }
//     void Init(const std::string &name, int a, int b)
//     {
//         _name = name;
//         _a = a;
//         _b = b;
//     }
//     void Excute()
//     {
//         _result = _a + _b;
//     }
//     int Result() { return _result; }
//     std::string Name() { return _name; }
//     void SetId(pthread_t tid) { _tid = tid; }
//     pthread_t Id() { return _tid; }
//     int A() { return _a; }
//     int B() { return _b; }
//     ~ThreadData()
//     {
//     }

// private:
//     std::string _name;
//     int _a;
//     int _b;
//     int _result;
//     pthread_t _tid;
// };

// #define NUM 10

// void *routine(void *arg)
// {
//     ThreadData *td = static_cast<ThreadData *>(arg);

//     while (true)
//     {
//         // 3. 不加保护的情况下，显示器文件就是共享资源！
//         std::cout << "我是新线程,我的名字是: " << td->Name() << ", my tid is : " << ToHex(pthread_self()) << "， 全局变量(会修改)：" << gval << std::endl;
//         gval++;
//         td->Excute();
//         sleep(1);
//         break;
//     }

//     return td;
// }

// int main()
// {
//     ThreadData td[NUM];
//     // 准备要加工的数据
//     for (int i = 0; i < NUM; i++)
//     {
//         char id[64];
//         snprintf(id, sizeof(id), "thread-%d", i);
//         td[i].Init(id, i * 10, i * 20);
//     }

//     // 创建多线程
//     for (int i = 0; i < NUM; i++)
//     {
//         pthread_t tid;
//         pthread_create(&tid, nullptr, routine, &td[i]);
//         td[i].SetId(tid);
//     }

//     // 等待多个线程
//     for (int i = 0; i < NUM; i++)
//     {
//         pthread_join(td[i].Id(), nullptr);
//     }

//     // 汇总处理结果
//     for (int i = 0; i < NUM; i++)
//     {
//         printf("td[%d]: %d+%d=%d[%ld]\n", i, td[i].A(), td[i].B(), td[i].Result(), td[i].Id());
//     }

//     while (true)
//     {
//         std::cout << "我是mani线程" << std::endl;
//         sleep(1);
//     }

//     return 0;
// }

// void *routine(void *arg)
// {
//     std::string name = static_cast<const char*>(arg);

//     //在不保护的情况下，显示器文件就是共享资源
//     while(true)
//     {
//         std::cout << "我是新线程，我的名字是 ："<<name<<", my tid is : "<< ToHex(pthread_self())<<"，全局变量 ："<<gval<<std::endl;
//         sleep(1);
//     }

//     return 0;
// }

// int main()
// {
//     // 1.新线程和main线程谁先运行？？？ 不确定
//     // 2.线程创建出来就是对时间片进行划分
//     pthread_t tid1;
//     pthread_create(&tid1, nullptr, routine, (void *)"thread-1");

//     pthread_t tid2;
//     pthread_create(&tid2, nullptr, routine, (void *)"thread-2");

//     pthread_t tid3;
//     pthread_create(&tid3, nullptr, routine, (void *)"thread-3");

//     pthread_t tid4;
//     pthread_create(&tid4, nullptr, routine, (void *)"thread-4");

//     printf("new thread id : 0x%lx",tid1);
//     printf("new thread id : 0x%lx",tid2);
//     printf("new thread id : 0x%lx",tid3);
//     printf("new thread id : 0x%lx",tid4);

//     while(true)
//     {
//         std::cout << "我是mani线程"<<std::endl;
//         sleep(1);
//     }

//     return 0;
// }

// void *rout(void *arg)
// {
//     for(; ;)
//     {
//         printf("I am thread 1\n");
//         sleep(1);
//     }
// }

// void *thread_run(void* arg)
// {
//     pthread_detach(pthread_self());
//     printf("%s\n",(char*)arg);
//     return nullptr;
// }

// int main()
// {
//     pthread_t tid;

//     if(pthread_create(&tid,NULL,thread_run,(void*)"thread1 run....") != 0)
//     {
//        printf("pthread creat error\n");
//        return 1;
//     }

//     sleep(1);//先分离再进行等待
//     int ret = 0;

//     if(pthread_join(tid,NULL) == 0)
//     {
//         std::cout << "wait thead sucess "<<std::endl;
//         ret = 1;
//     }
//     else
//     {
//         std::cout << "wait thread fail "<<std::endl;
//         ret = 0;
//     }

//     return ret;
// }